<?php
namespace App\Common\Lib\Hyperf;

use App\Common as com;
use Dotenv\Dotenv;
use Psr\Container\ContainerInterface;
use Symfony\Component\Finder\Finder;
use Hyperf\Config\Config;
use Hyperf\Config\ProviderConfig;
use Dotenv\Repository\Adapter;
use Dotenv\Repository\RepositoryBuilder;

class ConfigFactory {
	public function __invoke(ContainerInterface $container)
	{
		// Load env before config.
		if (file_exists(BASE_PATH . '/.env')) {
			$repository = RepositoryBuilder::createWithNoAdapters()
				->addAdapter(Adapter\PutenvAdapter::class)
				->immutable()
				->make();

			Dotenv::create($repository, [BASE_PATH])->load();
		}

		$configPath = BASE_PATH . '/config/';
		$config = $this->readConfig($configPath . 'config.php');
		$serverConfig = $this->readConfig($configPath . 'server.php');
		$autoloadConfig = $this->readPaths([BASE_PATH . '/config/autoload']);
		$merged = array_merge_recursive(ProviderConfig::load(), $serverConfig, $config, ...$autoloadConfig);
		// load env
		$envConfig = $this->readPaths([BASE_PATH . '/config/env']);
		$merged = array_merge($merged, ...$envConfig);
		//
		return new Config($merged);
	}

	private function readConfig(string $configPath): array
	{
		$config = [];
		if (file_exists($configPath) && is_readable($configPath)) {
			$config = require $configPath;
		}
		return is_array($config) ? $config : [];
	}

	private function readPaths(array $paths)
	{
		$configs = [];
		$finder = new Finder();
		$finder->files()->in($paths)->name('*.php');
		foreach ($finder as $file) {
			$configs[] = [
				$file->getBasename('.php') => require $file->getRealPath(),
			];
		}
		return $configs;
	}
}
